#include "application_test.h"

int ED_Event(void *msg, int tag_type, int sender, int *msgc, int **destv, void **msgv, int **type_msgv) {
	*msgc = 0;
	printf("APPLICATION MSG: ED_Event!\n");
	if (msg != NULL) {
		printf("%% %d %% - Message:  [%d] from %d !\n", ranka, ((struct msgstruct *) msg)->msg[0], sender);
	}
	if (msg == NULL) {
		//Process zero sends the message to all of his neighbors
		*msgc = neighca;
		*destv= createDestv(*msgc, 1);
		*type_msgv = createTypev(*msgc, 1, type_index);

		*msgv = (void *) createMsgv(*msgc, 42);
	}
	else {
		count++;
		if(count == neighca && ranka == 0) {
			printf("\n\n\n\nFIM DE EXECUCAO (%d/%d)\n\n\n\n", count, neighca);
			return 0;
		}
		if(parent == -1) {
			if(ranka != 0)
				parent = sender;
			if(neighca -1 == 0) {
				*msgc = 0 ;
				goto saidoif;
			}
			*msgc = neighca-1;
			*destv = createDestv(*msgc, 1);
			*type_msgv = createTypev(*msgc, 1, type_index);

			*msgv = (void *) createMsgv(*msgc, 42);
		}
		saidoif:
		printf("%% %d %% - Count vale: %d/%d\n",ranka, count, neighca);
		if(count == neighca) {
			printf("\n\n%% %d %% - Enviando feddback para parent %d \n\n\n",ranka, parent);
			*msgc = 1;
			*destv= createDestv(*msgc, 0);
//			destv[0] = parent;
			*type_msgv = createTypev(*msgc, 1, type_index);
			*msgv = (void *) createMsgv(*msgc, 42);
			return 0;
		}
		printf("%% %d %% - Parent [%d] and count %d/%d !\n", ranka,  parent, count, neighca);
	}
	if(*msgc == 0) {
		destv = 0;
		msgv = 0;
		type_msgv = 0;
	}
	printf("------------------------------\n");
	printf("%% %d %% - ED_Event sent %d msgs\n", ranka, *msgc);
	printf("------------------------------\n");
	return 1;
}

int *createTypev(int tam, int all, int set) {
	int *destvaux, cont = 1;
	destvaux = malloc(tam * sizeof(int));
	if (all != -1)
		for (i = 0; i < tam; i++)
			destvaux[i] = set;
	return destvaux;
}

int *createDestv(int tam, int noparent) {
	printf("%% %d %% - Escolhendo ranks, meu pai eh: %d\n", ranka, parent);
	int *destvaux, cont = 1;
	destvaux = malloc(tam * sizeof(int));
	int parent_index = -1;
	int k = 0;
	if(!noparent) {
		destvaux[0] = parent;
	} else {
		for (i = 0; i < neighca; i++) {
			if(neighva[i] != parent) {
				destvaux[k] = neighva[i];
				k++;
			}
			if(k >= tam) 
				break;
		}
	}
	for (i = 0; i < tam; i++) {
		printf("%% %d %% - Rank escolhido: %d\n", ranka, destvaux[i]);
	}
	return destvaux;
}

struct msgstruct *createMsgv(int tam, int ini) {
	struct msgstruct *msgvaux;

	msgvaux = (struct msgstruct *) malloc(tam * sizeof(struct msgstruct));

	for (i = 0; i < tam; i++) {
		msgvaux[i].msg[0] = ini;
		#ifndef NOT_USE_PRINTF 
		printf("APPLICATION MSG: I am %d and I'm sending message %d!\n", ranka, msgvaux[i].msg[0]);
		#endif
	}
	return msgvaux;
}

int ED_Init(int argc, char *argv[], int rank, int neighc, int *neighv) {
	neighca=neighc;
	neighva=neighv;
  type_index = ED_Create_derived_datatype(1, blocklengths, types, sizeof(struct msgstruct));
  ranka = rank;
	parent = -1;
	printf("%% %d %%: I've %d neighbors!\n", ranka, neighc);
/*	for(i = 0; i < neighca; ++i) 
    	printf("%% %d %% Meu vizinho eh %d !\n", ranka,  neighva[i]);*/

}

int ED_Msg_buff_allocate(int size, int neigh, void **buff){
 *buff = malloc(size);
}
int ED_Finalize(){
}		
